package com.gyl.dao.impl;

import java.io.Serializable;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

import com.gyl.dao.BaseDao;
import com.gyl.query.BaseQuery;
import com.gyl.query.PageResult;
import com.gyl.utils.GenericSuperClass;

/**  
* @Name: BaseDaoImpl<T>
* @Description: 抽象Dao实现类，封装CRUD操作
* @Author: 李超
* @Create Date: 2016-11-30
*/
public class BaseDaoImpl<T> extends HibernateDaoSupport implements BaseDao<T> {
	
	//范类转换：获取泛型BaseDaoImpl<T>的参数T的具体类型
	private Class entity = GenericSuperClass.getSuperClass(this.getClass()) ;
	
	/**  
	* @Name: setSessionFactoryDi（方法的名称）
	* @Description: 注入sessionFactory（方法的描述）
	* @Author: 李超（作者） 
	* @Version: V1.00 （版本号）
	* @Create Date: 2016-11-30 （创建日期）
	* @Parameters: SessionFactory sessionFactory sessionFactory对象（方法的入参，如果没有，填写为“无”）
	* @Return: 无 分页查询结果（返回值，如果没有，填写为“无”）
	*/
	@Autowired
	@Qualifier("sessionFactory")
	public final void setSessionFactoryDi(SessionFactory sessionFactory) {
		super.setSessionFactory(sessionFactory) ;
	}

	/**  
	* @Name: findPageResult（方法的名称）
	* @Description: 分页查询（方法的描述）
	* @Author: 李超（作者） 
	* @Version: V1.00 （版本号）
	* @Create Date: 2016-11-30 （创建日期）
	* @Parameters: BaseQuery baseQuery 查询条件（方法的入参，如果没有，填写为“无”）
	* @Return: PageResult<T> 分页查询结果（返回值，如果没有，填写为“无”）
	*/
	@SuppressWarnings("unchecked")
	public PageResult<T> findPageResult(final BaseQuery baseQuery) {
		//实例化PageResult<T>对象，初始化currentPage，pageSize，totalRows的值
		PageResult<Object> result = new PageResult<Object>(baseQuery.getCurrentPage(), baseQuery.getPageSize(), this.getEntryCount(baseQuery)) ;
		//拼接hql语句
		String hql = "from " + entity.getSimpleName() + " o where 1=1 " ;
		StringBuffer buffer = new StringBuffer() ;
		Map<String, Object> queryMap = baseQuery.getQueryMap() ;
		if(queryMap != null && queryMap.size() > 0) {
			for(Map.Entry<String, Object> entry : queryMap.entrySet()) {
				buffer.append(" and " + entry.getKey() + " like '%" + entry.getValue() + "%'") ;
			}
		}
		final String finalHql = hql + buffer.toString() ;
		//获取rows：当前分页记录
		List<Object> list = (List<Object>) this.getHibernateTemplate().execute(new HibernateCallback<Object>() {
			public List<Object> doInHibernate(Session session) throws HibernateException,
					SQLException {
				Query query = session.createQuery(finalHql) ;
				query.setFirstResult((baseQuery.getCurrentPage()-1)*baseQuery.getPageSize()) ;
				query.setMaxResults(baseQuery.getPageSize()) ;
				return (List<Object>) query.list();
			}
		}) ;
		result.setRows(list) ;
		return (PageResult<T>) result;
	}

	/**  
	* @Name: findAllEntry（方法的名称）
	* @Description: 查询所有的对象集合，不分页（方法的描述）
	* @Author: 李超（作者） 
	* @Version: V1.00 （版本号）
	* @Create Date: 2016-11-30 （创建日期）
	* @Parameters: 无（方法的入参，如果没有，填写为“无”）
	* @Return: Collection<T> 查询结果（返回值，如果没有，填写为“无”）
	*/
	public Collection<T> findAllEntry() {
		return this.getHibernateTemplate().find("from " + entity.getSimpleName()) ;
	}

	/**  
	* @Name: findEntryById（方法的名称）
	* @Description: 根据id查询对象（方法的描述）
	* @Author: 李超（作者） 
	* @Version: V1.00 （版本号）
	* @Create Date: 2016-11-30 （创建日期）
	* @Parameters: Serializable id 主键id（方法的入参，如果没有，填写为“无”）
	* @Return: T 查询结果（返回值，如果没有，填写为“无”）
	*/
	public T findEntryById(Serializable id) {
		return (T) this.getHibernateTemplate().get(entity, id);
	}

	/**  
	* @Name: getEntriesByIds（方法的名称）
	* @Description: 根据id数组查询对象集合（方法的描述）
	* @Author: 李超（作者） 
	* @Version: V1.00 （版本号）
	* @Create Date: 2016-11-30 （创建日期）
	* @Parameters: Serializable ids 主键id数组（方法的入参，如果没有，填写为“无”）
	* @Return: Set<T> 返回对象集合（返回值，如果没有，填写为“无”）
	*/
	public Set<T> findEntriesByIds(Serializable ... ids) {
		Set<Object> entitie = new HashSet<Object>() ;
		for(Serializable id : ids) {
			Object object = this.getHibernateTemplate().get(entity, id) ;
			entitie.add(object) ;
		}
		return (Set<T>) entitie;
	}

	/**  
	* @Name: saveEntry（方法的名称）
	* @Description: 保存对象（方法的描述）
	* @Author: 李超（作者） 
	* @Version: V1.00 （版本号）
	* @Create Date: 2016-11-30 （创建日期）
	* @Parameters: T entity 待保存的对象（方法的入参，如果没有，填写为“无”）
	* @Return: 无（返回值，如果没有，填写为“无”）
	*/
	public void saveEntry(T entity) {
		this.getHibernateTemplate().save(entity) ;
	}

	/**  
	* @Name: saveEntries（方法的名称）
	* @Description: 保存对象集合（方法的描述）
	* @Author: 李超（作者） 
	* @Version: V1.00 （版本号）
	* @Create Date: 2016-11-30 （创建日期）
	* @Parameters: Collection<T> entities 待保存的对象集合（方法的入参，如果没有，填写为“无”）
	* @Return: 无（返回值，如果没有，填写为“无”）
	*/
	public void saveEntries(Collection<T> entities) {
		this.getHibernateTemplate().saveOrUpdateAll(entities) ;
	}

	/**  
	* @Name: updateEntry（方法的名称）
	* @Description: 更新对象（方法的描述）
	* @Author: 李超（作者） 
	* @Version: V1.00 （版本号）
	* @Create Date: 2016-11-30 （创建日期）
	* @Parameters:T entity 待更新的对象（方法的入参，如果没有，填写为“无”）
	* @Return: 无（返回值，如果没有，填写为“无”）
	*/
	public void updateEntry(T entity) {
		this.getHibernateTemplate().update(entity) ;
	}

	/**  
	* @Name: deleteEntry（方法的名称）
	* @Description: 根据id删除对象（方法的描述）
	* @Author: 李超（作者） 
	* @Version: V1.00 （版本号）
	* @Create Date: 2016-11-30 （创建日期）
	* @Parameters:Serializable id 主键id（方法的入参，如果没有，填写为“无”）
	* @Return: 无（返回值，如果没有，填写为“无”）
	*/
	public void deleteEntry(Serializable id) {
		Object object = this.getHibernateTemplate().get(entity, id) ;
		this.getHibernateTemplate().delete(object) ;
	}

	/**  
	* @Name: deleteEntriedByIds（方法的名称）
	* @Description: 根据id数组删除对象集合（方法的描述）
	* @Author: 李超（作者） 
	* @Version: V1.00 （版本号）
	* @Create Date: 2016-11-30 （创建日期）
	* @Parameters:Serializable ... ids 主键id数组（方法的入参，如果没有，填写为“无”）
	* @Return: 无（返回值，如果没有，填写为“无”）
	*/
	public void deleteEntriedByIds(Serializable... ids) {
		List<Object> entities = new ArrayList<Object>() ;
		for(Serializable id : ids) {
			Object object = this.getHibernateTemplate().get(entity, id) ;
			entities.add(object) ;
		}
		this.getHibernateTemplate().deleteAll(entities) ;
	}

	/**  
	* @Name: deleteEntitiesByCollection（方法的名称）
	* @Description: 删除对象集合（方法的描述）
	* @Author: 李超（作者） 
	* @Version: V1.00 （版本号）
	* @Create Date: 2016-11-30 （创建日期）
	* @Parameters:Collection<T> entities 待删除的对象集合（方法的入参，如果没有，填写为“无”）
	* @Return: 无（返回值，如果没有，填写为“无”）
	*/
	public void deleteEntitiesByCollection(Collection<T> entities) {
		this.getHibernateTemplate().deleteAll(entities) ;
	}
	
	/**  
	* @Name: getEntryCount（方法的名称）
	* @Description: 获取总记录数（方法的描述）
	* @Author: 李超（作者） 
	* @Version: V1.00 （版本号）
	* @Create Date: 2016-11-30 （创建日期）
	* @Parameters: BaseQuery baseQuery 封装页面查询参数（方法的入参，如果没有，填写为“无”）
	* @Return: int 返回总记录数（返回值，如果没有，填写为“无”）
	*/
	public int getEntryCount(BaseQuery baseQuery) {
		//拼接hql语句
		String hql = "from " + entity.getSimpleName() + " o where 1=1 " ;
		StringBuffer buffer = new StringBuffer() ;
		Map<String, Object> queryMap = baseQuery.getQueryMap() ;
		if(queryMap != null && queryMap.size() > 0) {
			for(Map.Entry<String, Object> entry : queryMap.entrySet()) {
				buffer.append(" and " + entry.getKey() + " like '%" + entry.getValue() + "%'") ;
			}
		}
		final String finalHql = hql + buffer.toString() ;
		//获取查询总记录数
		return this.getHibernateTemplate().execute(new HibernateCallback<Integer>() {
			public Integer doInHibernate(Session session) throws HibernateException,
					SQLException {
				Query query = session.createQuery(finalHql) ;
				return query.list().size();
			}
		}) ;
	}
}
